package com.jd.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

/**
 * 资源服务器配置
 * 内部关联了ResourceServerSecurityConfigurer和HttpSecurity。前者与资源安全配置相关，后者与http安全配置相关
 * 
 * @author xiazhengjiao
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

	/**
	 * 资源安全配置
	 */
	@Override
	public void configure(ResourceServerSecurityConfigurer resources) {
		//resourceId 用于分配给可授予的clientId
		//stateless  标记以指示在这些资源上仅允许基于令牌的身份验证
		resources.resourceId("order").stateless(true);
	}

	/**
	 * http安全配置
	 */
	@Override
	public void configure(HttpSecurity http) throws Exception {
		
		http.authorizeRequests().anyRequest().authenticated()
				.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
					public <O extends FilterSecurityInterceptor> O postProcess(O fsi) {
						fsi.setSecurityMetadataSource(mySecurityMetadataSource()); //
						fsi.setAccessDecisionManager(myAccessDecisionManager()); //
						return fsi;
					}
				});
	}

	@Bean
	public FilterInvocationSecurityMetadataSource mySecurityMetadataSource() {
		CustomInvocationSecurityMetadataSourceImp securityMetadataSource = new CustomInvocationSecurityMetadataSourceImp();
		return securityMetadataSource;
	}

	@Bean
	public AccessDecisionManager myAccessDecisionManager() {
		return new CustomAccessDecisionManager();
	}

}
